using System;
using System.Collections.Generic;
using System.Text;
using FlatRedBall;
using FlatRedBall.Input;
using FlatRedBall.AI.Pathfinding;
using FlatRedBall.Graphics.Animation;
using FlatRedBall.Graphics.Particle;
using FlatRedBall.Audio;

using FlatRedBall.Math.Geometry;
using FlatRedBall.Math.Splines;
using BitmapFont = FlatRedBall.Graphics.BitmapFont;
using Cursor = FlatRedBall.Gui.Cursor;
using GuiManager = FlatRedBall.Gui.GuiManager;

#if FRB_XNA || SILVERLIGHT
using Keys = Microsoft.Xna.Framework.Input.Keys;
using Vector3 = Microsoft.Xna.Framework.Vector3;
using Texture2D = Microsoft.Xna.Framework.Graphics.Texture2D;

using NereusGame.Entities.Projectiles;
#endif

namespace NereusGame.Entities.Weapons
{
    public partial class Gun
    {
        private const float CONE1_ANGLE = (float)Math.PI / 6f;
        private const float CONE2_ANGLE = (float)Math.PI / 5f;
        private const int MAX_AMMO = 25;


        private void CustomInitialize()
        {
            Name = "Gun";
            InitializeAmmo();
            fireRate = initialFireRate = 10;
            defaultVelocity = 40;
            damage = 2;


        }

        private void CustomActivity()
        {


        }

        private void CustomDestroy()
        {

            base.Destroy();
        }

        private static void CustomLoadStaticContent(string contentManagerName)
        {


        }

        private void InitializeAmmo()
        {
            for (int i = 0; i < MAX_AMMO; i++)
                deadAmmo.Enqueue(new Bullet(CONTEN_MANAGER));
        }


        protected override void Upgrade1()
        {
            damage++;
        }

        protected override void Upgrade2()
        {
            
            fireRate = initialFireRate /2;

        }

        protected override void Upgrade3()
        {
            
        }

        protected override void Upgrade4()
        {
            
        }

        protected override void Upgrade5()
        {
            damage++;
            fireRate = initialFireRate / 2;
        }

        public override void Shoot1(Vector3 pos, float offset, float rotation, Vector3 velocity)
        {
            base.Shoot1(pos, offset, rotation, velocity);
        }

        public override void Shoot3(Vector3 pos, float offset, float rotation, Vector3 velocity)
        {
            if (state == WeaponState.ReadyToShoot)
            {
                // calculate direciton
                shootingPosition.X = (float)Math.Cos(rotation + (float)Math.PI / 2f) + pos.X;
                shootingPosition.Y = (float)Math.Sin(rotation + (float)Math.PI / 2f) + pos.Y;
                Vector3 direction = (shootingPosition - pos);
                direction.Normalize();

                // calculate shootingposition
                shootingPosition = pos + direction * offset;
                shoot2Bullets(direction, rotation, velocity);
                state = WeaponState.DownTime;
            }
        }

        public override void Shoot4(Vector3 pos, float offset, float rotation, Vector3 velocity)
        {
            if (state == WeaponState.ReadyToShoot)
            {
                // calculate direciton
                shootingPosition.X = (float)Math.Cos(rotation + (float)Math.PI / 2f) + pos.X;
                shootingPosition.Y = (float)Math.Sin(rotation + (float)Math.PI / 2f) + pos.Y;
                Vector3 direction = (shootingPosition - pos);
                direction.Normalize();

                // calculate shootingposition
                shootingPosition = pos + direction * offset;
                shoot4Bullets( direction, rotation, velocity, pos, offset);

                state = WeaponState.DownTime;
            }

        }

        public override void Shoot5(Vector3 pos, float offset, float rotation, Vector3 velocity)
        {
             if (state == WeaponState.ReadyToShoot)
            {
                // calculate direciton
                shootingPosition.X = (float)Math.Cos(rotation + (float)Math.PI / 2f) + pos.X;
                shootingPosition.Y = (float)Math.Sin(rotation + (float)Math.PI / 2f) + pos.Y;
                Vector3 direction = (shootingPosition - pos);
                direction.Normalize();

                // calculate shootingposition
                shootingPosition = pos + direction * offset;
                shoot6Bullets(direction, rotation, velocity, pos, offset);

                state = WeaponState.DownTime;
            }
          
        }


        private void shoot2Bullets( Vector3 direction, float rotation, Vector3 velocity)
        {
            Vector3 perp2 = Vector3.Zero;
            Vector3 perp1 = Vector3.Zero;

            float offset = deadAmmo.Peek().Tex.ScaleX * 2f;

            perp1.X = -direction.Y;
            perp2.Y = direction.X;

            perp2.X = direction.Y;
            perp2.Y = -direction.X;


            deadAmmo.Peek().Position = shootingPosition + (perp1 * offset);  // this will set the position of the projectile
            deadAmmo.Peek().Shoot(Shooter, direction, rotation, velocity);
            aliveAmmo.Enqueue(deadAmmo.Dequeue());  // send it to the aliveAmmo queue.


            deadAmmo.Peek().Position = shootingPosition + (perp2 * offset);  // this will set the position of the projectile
            deadAmmo.Peek().Shoot(Shooter, direction, rotation, velocity);
            aliveAmmo.Enqueue(deadAmmo.Dequeue());  // send it to the aliveAmmo queue.

        }


        private void shoot4Bullets( Vector3 direction, float rotation, Vector3 velocity, Vector3 pos, float offset)
        {

            shoot2Bullets( direction, rotation, velocity);

            // calculate direciton
            shootingPosition.X = (float)Math.Cos(rotation -(CONE1_ANGLE) + (float)Math.PI / 2f) + pos.X;
            shootingPosition.Y = (float)Math.Sin(rotation - (CONE1_ANGLE) + (float)Math.PI / 2f) + pos.Y;
            Vector3 direction1 = (shootingPosition - pos);
            direction1.Normalize();


            shootingPosition.X = (float)Math.Cos(rotation + (CONE1_ANGLE) + (float)Math.PI / 2f) + pos.X;
            shootingPosition.Y = (float)Math.Sin(rotation + (CONE1_ANGLE) + (float)Math.PI / 2f) + pos.Y;
            Vector3 direction2 = (shootingPosition - pos);
            direction2.Normalize();

            // calculate shootingposition
            shootingPosition = pos + direction1 * offset;
            deadAmmo.Peek().Position = shootingPosition;  // this will set the position of the projectile
            deadAmmo.Peek().Shoot(Shooter, direction1, rotation - (CONE1_ANGLE), velocity);
            aliveAmmo.Enqueue(deadAmmo.Dequeue());  // send it to the aliveAmmo queue.

            shootingPosition = pos + direction2 * offset;
            deadAmmo.Peek().Position = shootingPosition;  // this will set the position of the projectile
            deadAmmo.Peek().Shoot(Shooter, direction2, rotation + (CONE1_ANGLE), velocity);
            aliveAmmo.Enqueue(deadAmmo.Dequeue());  // send it to the aliveAmmo queue.

        }


        private void shoot6Bullets(Vector3 direction, float rotation, Vector3 velocity, Vector3 pos, float offset)
        {
            shoot4Bullets(  direction,  rotation,  velocity,  pos,  offset);

            // calculate direciton
            shootingPosition.X = (float)Math.Cos(rotation - (CONE2_ANGLE) + (float)Math.PI / 2f) + pos.X;
            shootingPosition.Y = (float)Math.Sin(rotation - (CONE2_ANGLE) + (float)Math.PI / 2f) + pos.Y;
            Vector3 direction1 = (shootingPosition - pos);
            direction1.Normalize();


            shootingPosition.X = (float)Math.Cos(rotation + (CONE2_ANGLE) + (float)Math.PI / 2f) + pos.X;
            shootingPosition.Y = (float)Math.Sin(rotation + (CONE2_ANGLE) + (float)Math.PI / 2f) + pos.Y;
            Vector3 direction2 = (shootingPosition - pos);
            direction2.Normalize();

            // calculate shootingposition
            shootingPosition = pos + direction1 * offset;
            deadAmmo.Peek().Position = shootingPosition;  // this will set the position of the projectile
            deadAmmo.Peek().Shoot(Shooter, direction1, rotation - (CONE2_ANGLE), velocity);
            aliveAmmo.Enqueue(deadAmmo.Dequeue());  // send it to the aliveAmmo queue.

            shootingPosition = pos + direction2 * offset;
            deadAmmo.Peek().Position = shootingPosition;  // this will set the position of the projectile
            deadAmmo.Peek().Shoot(Shooter, direction2, rotation + (CONE2_ANGLE), velocity);
            aliveAmmo.Enqueue(deadAmmo.Dequeue());  // send it to the aliveAmmo queue.


        }

        public override void playWeaponSound()
        {
            if (rand.Next(0, 1) == 0)
                AudioManager.Play(gunfire1);
            else
                AudioManager.Play(gunfire2);
        }

    }
}


